﻿using System;
using System.Collections.Generic;
using DataCenter.Interface.Model;

namespace DataCenter.Component
{
    public class TimeQueue
    {
        public TimeQueue()
        {
            this.regionList = new List<TimeRegion>();
        }
        public TimeQueue(TimeRegion region)
            :this()
        {
            this.regionList.Add(region);
        }

        private List<TimeRegion> regionList;

        public List<TimeRegion> RegionList
        {
            get { return regionList; }
            set { regionList = value; }
        }

        public void AddRegion(DateTime time, ObjectEntity objectEntity)
        {
            TimeRegion region = FindRegion(time, objectEntity.ObjectId);
            if (region != null)
            {
                if (region.Time0.Date == region.Time1.Date)
                {
                    TimeRegion region0 = FindRegion(time, region.Time1);
                    if (region0 == null) region.Time0 = time;
                    else
                    {
                        region0.CombinObject(region);
                        regionList.Remove(region);
                    }
                }
                else
                {
                    if (region.Time0 != time && region.Time1 != time)
                    {
                        CreateRegion(region.Time0, time.Date, objectEntity);
                        CreateRegion(time, region.Time1, objectEntity);

                        region.RemoveObject(objectEntity.ObjectId);
                        if (region.ObjectCount == 0) regionList.Remove(region);
                    }
                }
            }
        }

        public void RemoveRegion(DateTime date, ObjectEntity objectEntity)
        {
            TimeRegion region = FindRegion(date, objectEntity.ObjectId);
            if (region != null)
            {
                if (date == region.Time0.Date)
                {
                    DateTime time = region.Time0.AddDays(1).Date;
                    if (time <= region.Time1)
                        CreateRegion(time, region.Time1, objectEntity);
                }
                else if (date == region.Time1.Date)
                {
                    DateTime time = region.Time1.AddDays(-1).Date;
                    if (time >= region.Time0)
                        CreateRegion(region.Time0, time, objectEntity);
                }
                else
                {
                    CreateRegion(region.Time0, date, objectEntity);
                    CreateRegion(date.AddDays(1).Date, region.Time1, objectEntity);
                }
                region.RemoveObject(objectEntity.ObjectId);
                if (region.ObjectCount == 0) regionList.Remove(region);
            }
        }

        private TimeRegion FindRegion(DateTime time, int objectId)
        {
            foreach (TimeRegion region in regionList)
            {
                if(region.IsInRegion(time, objectId))
                {
                    return region;
                }
            }
            return null;
        }

        private TimeRegion FindRegion(DateTime time0, DateTime time1)
        {
            foreach (TimeRegion region in regionList)
            {
                if (region.Time0 == time0 && region.Time1 == time1)
                    return region;
            }
            return null;
        }

        private TimeRegion CreateRegion(DateTime time0, DateTime time1, ObjectEntity objectEntity)
        {
            TimeRegion region = FindRegion(time0, time1);
            if (region == null)
            {
                region = new TimeRegion(time0, time1);
                regionList.Add(region);
            }
            region.AddObject(objectEntity);
            return region;
        }
    }
}
